import InDB from 'indb'

const idb = new InDB({
    name: 'mqttv',
    version: 1,
    stores: [
        {
            name: 'project',
            keyPath: 'id',
            autoIncrement: true,
        },
        {
            name: 'server',
            keyPath: 'id',
            autoIncrement: true,
        },
        {
            name: 'trigger',
            keyPath: 'id',
            autoIncrement: true,
            indexes: [
                {
                    name: 'pid',
                    keyPath: 'pid',
                }
            ]
        },
    ],
})

const storeProjecct = idb.use('project')
const storeServer = idb.use('server')
const storeTrigger = idb.use('trigger')

/**
 * 客户端, 触发器集合
 */
export class Project {
    /**
     * 客户端构造
     * @param name 名称
     * @param desc 描述
     */
    constructor(name, desc) {
        this.name = name
        this.desc = desc
    }

    /**
     * 保存
     * @returns {Promise<void>}
     */
    async save() {
        let keys = await storeProjecct.keys()
        // 自增长id
        if (!this.id) {
            if (!keys || keys.length <= 0) {
                this.id = 1
            } else {
                this.id = keys[keys.length - 1] + 1
            }
        }
        await storeProjecct.put(this)
    }

    /**
     * 获取全部客户端
     * @returns {Promise<*>}
     */
    static async getAll(){
        return await storeProjecct.all()
    }

    /**
     * 删除客户端
     * @param id
     * @returns {Promise<*>}
     */
    static async del(id){
        if(id){
            return await storeProjecct.delete(id)
        }
    }

    /**
     * 根据id获取
     * @param id
     * @returns {Promise<*>}
     */
    static async getId(id){
        if(id){
            return await storeProjecct.get(id)
        }
    }
}

/**
 * mqtt服务器
 */
export class Server {

    /**
     * 服务器构造
     * @param name 服务器名称
     * @param url 连接url
     * @param uname 用户名
     * @param passwd 密码
     * @param version mqtt版本
     * @param timeout 超时时长
     * @param autoreconnect 是否自动重连
     * @param reconnect 重连周期
     * @param clean 是否清除session
     * @param keepalive 是否保活
     */
    constructor(name, url, uname, passwd, version='3.1.1', timeout=5000, autoreconnect=false, reconnect=0, clean=true, keepalive=60000) {
        this.name = name
        this.url = url
        this.uname = uname
        this.passwd = passwd
        this.version = version
        this.timeout = timeout
        this.autoreconnect = autoreconnect
        this.reconnect = reconnect
        this.clean = clean
        this.keepalive = keepalive
    }

    /**
     * 保存
     * @returns {Promise<void>}
     */
    async save() {
        let keys = await storeServer.keys()
        if(!this.id) {
            if (!keys || keys.length <= 0) {
                this.id = 1
            } else {
                this.id = keys[keys.length - 1] + 1
            }
        }
        await storeServer.put(this)
        return this
    }

    /**
     * 删除服务器
     * @param id
     * @returns {Promise<void>}
     */
    static async del(id){
        if(id){
            await storeServer.delete(id)
        }
    }

    /**
     * 获取全部服务器
     * @returns {Promise<*>}
     */
    static async getAll(){
        return await storeServer.all()
    }

    static async getId(id){
        return await storeServer.get(id)
    }
}

/**
 * 触发器, 无数据结构
 */
export class Trigger {
    /**
     * 触发器构造
     * @param pid 项目id
     * @param topic 监听topic
     * @param value 发送内容
     * @param trigger 触发方式
     * @param cbtopic 触发发送topic
     */
    constructor(pid, topic, value, trigger, cbtopic) {
        this.pid = pid
        this.topic = topic
        this.value = value
        this.trigger = trigger
        this.cbtopic = cbtopic
    }

    /**
     * 保存
     * @returns {Promise<void>}
     */
    async save() {
        let keys = await storeTrigger.keys()
        // 自增长id
        if (!this.id) {
            if (!keys || keys.length <= 0) {
                this.id = 1
            } else {
                this.id = keys[keys.length - 1] + 1
            }
        }
        await storeTrigger.put(this)
    }

    /**
     * 基于客户端获取所有触发器
     * @returns {Promise<*>}
     */
    static async getAll(pid){
        return await storeTrigger.query('pid', pid)
    }

    /**
     * 根据id查询
     * @param id
     * @returns {Promise<*>}
     */
    static async getId(id){
        return await storeTrigger.get(id)
    }

    /**
     * 删除触发器
     * @param id
     * @returns {Promise<*>}
     */
    static async del(id){
        if(id){
            return await storeTrigger.delete(id)
        }
    }
}